package designMode.compoundPattern;

/**
 * @author LIBOFEI
 * @ClassName Test
 * @description 哦，亲爱的，欢迎来到复合模式，这个复合不是分手的那种复合，嗯，是什么呢，让书本告诉你：
 *              复合模式通常被一起使用，并被组合在用一个设计解决方案中。
 *              复合模式在一个解决方案中结合两个或多个模式，已解决一般或重复发生的问题。
 * @date 2020/7/1 14:23
 * @Version 1.0
 **/
public class Test {
    public static void main(String[] args) {
        Test test = new Test();

        //1.叫 此时的叫 装饰者
        //test.simlate();


        //2.叫，使用了工厂，装饰者
        //AbstractDuckFactory factory = new CountingDuckFactory();
        //test.simlateByFactory(factory);

        //3.叫 使用了工厂，组合，装饰者
//        AbstractDuckFactory factory = new CountingDuckFactory();
//        test.simlateByComposite(factory);

        //4.叫 使用工厂，组合，观察者，装饰者
        AbstractDuckFactory factory = new CountingDuckFactory();
        test.simlateByObserver(factory);


        test.showCount();//统计呱呱呱叫声
    }

    void simlate(){
        Quackable greenDuck = new QuackCounter(new GreenDuck());
        Quackable redDuck = new QuackCounter(new RedDuck());
        Quackable rubberDuck = new QuackCounter(new RubberDuck());
        Quackable duckCall = new QuackCounter(new DuckCall());

        System.out.println("开始叫---by no");
        Quackologist quackologist = new Quackologist();
        simlate(greenDuck);
        simlate(redDuck);
        simlate(rubberDuck);
        simlate(duckCall);
        //只想去记录鸭子的叫声，不想去记录鹅的咯咯咯，所以鹅不使用装饰者装饰
        simlate(new GooseAdapter(new Goose()));
    }

    void simlateByFactory(AbstractDuckFactory factory){
        Quackable greenDuck = factory.createGreenDuck();
        Quackable redDuck = factory.createRedDuck();
        Quackable duckCall = factory.createDuckCall();
        Quackable rubberDuck = factory.createRubberDuck();

        System.out.println("开始叫--by factory");

        simlate(greenDuck);
        simlate(redDuck);
        simlate(rubberDuck);
        simlate(duckCall);
        //只想去记录鸭子的叫声，不想去记录鹅的咯咯咯，所以鹅不使用装饰者装饰
        simlate(new GooseAdapter(new Goose()));
    }

    void simlateByComposite(AbstractDuckFactory duckFactory){
        Quackable greenDuck = duckFactory.createGreenDuck();
        Quackable redDuck = duckFactory.createRedDuck();
        Quackable duckCall = duckFactory.createDuckCall();
        Quackable rubberDuck = duckFactory.createRubberDuck();

        System.out.println("开始叫--by composite");

        //创建总鸭子群
        Flock duckFlock = new Flock();
        duckFlock.add(greenDuck);
        duckFlock.add(redDuck);
        duckFlock.add(duckCall);
        duckFlock.add(rubberDuck);

        //创建绿鸭子小群
        Flock greenDucks = new Flock();
        Quackable greenChild1 = duckFactory.createGreenDuck();
        Quackable greenChild2 = duckFactory.createGreenDuck();
        Quackable greenChild3 = duckFactory.createGreenDuck();
        greenDucks.add(greenChild1);
        greenDucks.add(greenChild2);
        greenDucks.add(greenChild3);

        duckFlock.add(greenDucks);
        simlate(duckFlock);
    }


    void simlateByObserver(AbstractDuckFactory duckFactory){
        Quackable greenDuck = duckFactory.createGreenDuck();
        Quackable redDuck = duckFactory.createRedDuck();
        Quackable duckCall = duckFactory.createDuckCall();
        Quackable rubberDuck = duckFactory.createRubberDuck();

        System.out.println("开始叫--by observer");

        //创建总鸭子群
        Flock duckFlock = new Flock();
        duckFlock.add(greenDuck);
        duckFlock.add(redDuck);
        duckFlock.add(duckCall);
        duckFlock.add(rubberDuck);

        Quackologist quackologist = new Quackologist();
        duckFlock.registerObserver(quackologist);
        simlate(duckFlock);
    }


    void simlate(Quackable duck){
        duck.quack();
    }

    void showCount(){
        System.out.println("鸭子一共叫了" + QuackCounter.getNumberOfQuacks() + "声");
    }
}
